package org.pupil.socket.serialization.kryo;

import com.esotericsoftware.kryo.Kryo;
import com.esotericsoftware.kryo.io.Input;
import com.esotericsoftware.kryo.io.Output;
import org.pupil.socket.serialization.Serialization;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;

/**
 * @Description: Kryo序列化方式
 * @Author: pupil
 * @Date: 2024/07/22 下午 5:43
 */
public class KryoSerialization implements Serialization {

    private static final ThreadLocal<Kryo> kryos = new ThreadLocal<Kryo>() {
        @Override
        protected Kryo initialValue() {
            Kryo kryo = new Kryo();
            kryo.setRegistrationRequired(false);
            return kryo;
        }
    };

    @Override
    public <T> byte[] serialize(T obj) throws IOException {
        Output output = null;
        try {
            Kryo kryo = kryos.get();
            ByteArrayOutputStream os = new ByteArrayOutputStream();
            output = new Output(os);
            kryo.writeClassAndObject(output,obj);
            return output.toBytes();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }finally {
            if (output != null) {
                output.close();
            }
        }
    }

    @Override
    public <T> T deSerialize(byte[] data, Class<T> clazz) throws IOException {
        Input input = null;
        try {
            Kryo kryo = kryos.get();
            ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(data);
            input = new Input(byteArrayInputStream);
            return (T) kryo.readClassAndObject(input);
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            if (input != null) {
                input.close();
            }
        }
    }
}
